﻿using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace USU.MetricsMonitor.Common
{
	/// <summary>
	/// This structure represents svn 'revision'
	/// </summary>
	public struct Revision : IXmlSerializable, IEquatable<Revision>
	{
		private ulong Number;

		public override string ToString()
		{
			return Number.ToString();
		}

		private static void CheckForPositiveness(ulong number)
		{
			if (number == 0)
				throw new ArgumentException("Revision number must be positive");
		}

		public Revision(ulong number)
		{
			CheckForPositiveness(number);
			Number = number;
		}

		public Revision(string str)
		{
			var number = ulong.Parse(str);
			CheckForPositiveness(number);
			Number = number;
		}

		public static Revision operator +(Revision rev, ulong number)
		{
			return new Revision(rev.Number + number);
		}

		public static Revision operator -(Revision rev, ulong number)
		{
			return new Revision(rev.Number - number);
		}

		public static bool operator ==(Revision l, Revision r)
		{
			return l.Number == r.Number;
		}

		public static bool operator !=(Revision l, Revision r)
		{
			return !(l == r);
		}

		public long Long()
		{
			return (long)Number;
		}

		public bool Equals(Revision other)
		{
			return this == other;
		}

		public override bool Equals(object obj)
		{
			if (ReferenceEquals(null, obj)) return false;
			if (obj.GetType() != typeof(Revision)) return false;
			return Equals((Revision)obj);
		}

		public override int GetHashCode()
		{
			return (int)Number;
		}

		#region IXmlSerializable Members

		public XmlSchema GetSchema()
		{
			return null;
		}

		public void ReadXml(XmlReader reader)
		{
			var number = ulong.Parse(reader.ReadString());
			CheckForPositiveness(number);
			Number = number;
			reader.ReadEndElement();
		}

		public void WriteXml(XmlWriter writer)
		{
			writer.WriteString(Number.ToString());
		}

		#endregion
	}
}
